/**
 * @author:albert
 */
package com.bkbw.live.battle.business.ai;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.bkbw.live.battle.business.HateList;
import com.bkbw.live.battle.business.UnitObject;
import com.badlogic.gdx.ai.GdxAI;
import com.badlogic.gdx.ai.btree.Task;
import com.badlogic.gdx.ai.msg.Telegram;
import com.bkbw.live.common.GameConfig.UnitMoveMode;
import com.bkbw.live.common.GameConfig;
import com.bkbw.live.common.notifycenter.MessageDefine;

public class BtPursue<EntityType extends UnitObject> extends BaseLeafNode<EntityType>{
	List<Vector3D> paths;
	boolean stopMove = false;
	boolean userControlMove = false;
	Vector3D nextPoint;
	float pursueDt = 0;
	float pursueInterval = 1.5f;
	
	Logger logger = LoggerFactory.getLogger(GameConfig.LoggerName);
	@Override
	public void start() 
	{
		EntityType entity = getObject();
		entity.setMoveMode(UnitMoveMode.Target);
		if (paths == null || paths.size() == 0) {
			if (entity.isTargetAttackable()) {
				if (!entity.isTargetInDistance()) {
					Vector3D to = entity.getTargetEnemy().getPosition();
					//paths = entity.getMap().getAstarInfo().findPath(entity.getPosition(), to);
					if (entity.isNearTarget(to)){
						////logger.debug("pursue move no need to move");
						return;
					}
					
					paths = new LinkedList<Vector3D>();
					paths.add(entity.getPosition());
					paths.add(to);
					if (paths == null || paths.size() == 0) {
//						//logger.debug("pursue move no path find");
//						//logger.debug("pursue move start from " + entity.getPosition());
//						//logger.debug("pursue move end at " + to);
						return;
					}
					
					//logger.debug("pursue move start from " + entity.getPosition());
					if (paths != null && paths.size() > 0) {
						//logger.debug("pursue move end at " + paths.get(paths.size() - 1));
					}
				}
				
			}
			else {
				paths = null;
			}
		}
	
		if (paths != null && paths.size() > 0) {
			entity.setMoving(true);
			nextPoint = paths.get(0);
			entity.setMoveTarget(nextPoint);
			paths.remove(0);
		}
	}

	@Override
	public com.badlogic.gdx.ai.btree.Task.Status execute() {
		// TODO Auto-generated method stub
		// 寻路失败
		if (paths == null) {
			//logger.debug("pursue path null");
			return Status.FAILED;
		}
		
		// 用户控制
		if (userControlMove) {
			//logger.debug("pursue user control");
			return Status.FAILED;
		}
		
		// 行进中不知道碰到了什么，停止行走了
		if (stopMove) {
			//logger.debug("pursue stopmove");
			return Status.FAILED;
		}
		
		EntityType entity = getObject();
		if (entity.isTargetAttackable()) {
			// 追击中怪物进入攻击范围，结束追击
			//if (entity.isTargetInDistance()) {
			if (entity.isTargetInPursueDistance()) {
				//logger.debug("pursue succ");
				return Status.SUCCEEDED;
			}
			if (!entity.isTargetInSight()) {
				//logger.debug("out of sight");
				return Status.FAILED;
			}
		}
		// 当前追寻的怪物被干掉了，需要重新寻找目标
		else {
			//logger.debug("pursue no target");
			return Status.FAILED;
		}
		
		// 追了一段时间了，重新刷路
		pursueDt += GdxAI.getTimepiece().getDeltaTime();
		if (pursueDt > pursueInterval) {
			//entity.setTargetEnemy(null);
			pursueDt = 0;
			start();
			//return Status.SUCCEEDED;
			return Status.RUNNING;
		}
//		entity.getHateList().subHate(entity.getTargetEnemy().getId(), HateList.PursueReduce);
//		if (entity.switchTargetEnemyByHateWhenPursue()) {
//			return Status.SUCCEEDED;
//		}
		
		if (entity.isAtTarget(nextPoint)) {
			// 到达了路点的下一个目标，如果是最后一步
			if (paths.size() == 0) {
				//logger.debug("get destination");
				// 开始新的追击
				start();
				//return Status.SUCCEEDED;
				return Status.RUNNING;
			}
			else {
				//logger.debug("next edge");
				start();
				return Status.RUNNING;
			}
		}
		else {
			return Status.RUNNING;
		}
	}
	
	@Override
	public void end() 
	{
		paths = null;
		stopMove = false;
		EntityType entity = getObject();
		if (!userControlMove) {
			entity.setMoving(false);
		}
		userControlMove = false;
		////logger.debug("pursue end");
	}

	@Override
	protected Task<EntityType> copyTo(Task<EntityType> paramTask) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean handleMessage(Telegram paramTelegram) {
		// TODO Auto-generated method stub
		if (paramTelegram.message == MessageDefine.MOVE_STOP) {
			stopMove = true;
			return true;
		}
		else if (paramTelegram.message == MessageDefine.USER_CONTROL_MOVE) {
			userControlMove = true;
		}
		return false;
	}

}
